package vn.vfriends.mcms.admin.bean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.commons.codec.digest.DigestUtils;
import org.primefaces.context.RequestContext;
import org.primefaces.model.DualListModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import vn.vfriends.mcms.admin.model.Role;
import vn.vfriends.mcms.admin.model.User;
import vn.vfriends.mcms.admin.service.RoleService;
import vn.vfriends.mcms.admin.service.UserService;

/**
 *
 * @author tuan@vfriends.vn
 */
@Named
@ConversationScoped
public class UserBean implements Serializable {
    private final Logger logger = LoggerFactory.getLogger(UserBean.class);
    
    @Inject private UserService userService;
    @Inject private RoleService roleService;
    @Inject private Conversation conversation;
    private User[] selectedUsers;
    private User user;
    private List<User> userList;
    
    private DualListModel<Role> roleModels;
    
    @PostConstruct
    public void init(){
        List<Role> source = roleService.findRoles();
        roleModels = new DualListModel<Role>(source, new ArrayList<Role>());
        userList = userService.findUsers();
    }

    public List<User> getUserList() {
        return userList;
    }
    
    public User[] getSelectedUsers() {
        return selectedUsers;
    }

    public void setSelectedUsers(User[] selectedUsers) {
        this.selectedUsers = selectedUsers;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public DualListModel<Role> getRoleModels() {
        return roleModels;
    }

    public void setRoleModels(DualListModel<Role> roleModels) {
        this.roleModels = roleModels;
    }

    public Conversation getConversation() {
        return conversation;
    }
    
    public void preNewAction() {
        user = new User();
        
        if (conversation.isTransient()) {
            conversation.begin();
        }
    }
    
    public String preViewAction() {
        String outcome = "";
        FacesContext context = FacesContext.getCurrentInstance();
        
        try {
            if (conversation.isTransient()) {
                conversation.begin();
            }
            
            if(this.user != null) {
                outcome = "view?faces-redirect=true";
            }
            else if (this.selectedUsers == null || this.selectedUsers.length == 0) {
                if (RequestContext.getCurrentInstance() != null) {
                    RequestContext.getCurrentInstance().addCallbackParam("invalid", true);
                }
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Hãy chọn một người dùng", ""));
            } else if (this.selectedUsers.length > 1) {
                if (RequestContext.getCurrentInstance() != null) {
                    RequestContext.getCurrentInstance().addCallbackParam("invalid", true);
                }
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Hãy chọn chỉ một người dùng", ""));
            } else {
                this.user = this.selectedUsers[0];
                outcome = "view?faces-redirect=true";
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), ""));
        }
        return outcome;
    }
    
    public String preEditAction() {
        String outcome = null;
        FacesContext context = FacesContext.getCurrentInstance();
        try {
            if (conversation.isTransient()) {
                conversation.begin();
            }
            
            if(this.user != null){
                List<Role> roleList = this.roleService.findRoles();
                for(Role role : this.user.getRoles()){
                    roleList.remove(role);
                }
                this.roleModels.setSource(roleList);
                this.roleModels.setTarget(new ArrayList<Role>(this.user.getRoles()));
                outcome = "edit?faces-redirect=true";
            } else if (this.selectedUsers == null || this.selectedUsers.length == 0) {
                if (RequestContext.getCurrentInstance() != null) {
                    RequestContext.getCurrentInstance().addCallbackParam("invalid", true);
                }
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Hãy chọn một người dùng", ""));
            } else if (this.selectedUsers.length > 1) {
                if (RequestContext.getCurrentInstance() != null) {
                    RequestContext.getCurrentInstance().addCallbackParam("invalid", true);
                }
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Hãy chọn chỉ một người dùng", ""));
            } else {
                this.user = this.selectedUsers[0];
                List<Role> roleList = this.roleService.findRoles();
                for(Role role : this.user.getRoles()){
                    roleList.remove(role);
                }
                this.roleModels.setSource(roleList);
                this.roleModels.setTarget(new ArrayList<Role>(this.user.getRoles()));
                outcome = "edit?faces-redirect=true";
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), ""));

        }
        return outcome;
    }
    
    public void preDeleteAction() {
        FacesContext context = FacesContext.getCurrentInstance();
        try {
            if (conversation.isTransient()) {
                conversation.begin();
            }
            if ((this.user == null) && (this.selectedUsers == null || this.selectedUsers.length == 0)) {
                if (RequestContext.getCurrentInstance() != null) {
                    RequestContext.getCurrentInstance().addCallbackParam("invalid", true);
                }
                RequestContext.getCurrentInstance().addCallbackParam("invalid", true);
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Hãy chọn người dùng", ""));
            }
        } catch (Exception e) {
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), ""));
        }
    }
    
    public String saveAction() {
        try {
            user.setRoles(this.roleModels.getTarget());
            
            User existUser = this.userService.findUser(user.getId());
            String originalPassword = user.getPassword();
            String hashPassword = DigestUtils.md5Hex(user.getPassword());
            
            if(!existUser.getPassword().equals(hashPassword)){ // changed password
                //  MD5 hash password
                user.setPassword(hashPassword);
            }
            this.userService.createUser(user);
            return "view?faces-redirect=true";
        } catch (Exception ex) {
            this.logger.error(ex.getMessage(), ex);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), ""));
            return null;
        }
    }
    
    public String updateAction() {
        try {
            user.setRoles(new ArrayList<Role>());
            for(Role role : this.roleModels.getTarget()){
                user.getRoles().add(role);
            }
            User existUser = this.userService.findUser(user.getId());
            boolean isChangePassword = false;
            String originalPassword = user.getPassword();
            String hashPassword = DigestUtils.md5Hex(user.getPassword());
            if(!existUser.getPassword().equals(hashPassword)){ // changed password
                //  MD5 hash password
                user.setPassword(hashPassword);
                isChangePassword = true;
            }
            
            this.userService.editUser(user);
            return "view?faces-redirect=true";
        } catch (Exception ex) {
            this.logger.error(ex.getMessage(), ex);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), ""));
            return null;
        }
    }

    public String cancelAction() {
        conversation.end();
        return "list?faces-redirect=true";
    }
    
    public void deleteAction() {
        try {
            if(this.user != null) {
                this.userService.destroyUser(this.user.getId());
            }
            else {
                for(User selectedUser : selectedUsers) {
                    this.userService.destroyUser(selectedUser.getId());
                }
            }
            if(!conversation.isTransient()) {
                conversation.end();
            }
            FacesContext.getCurrentInstance().getExternalContext().redirect("list.jsf");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), ""));
        }
    }
}
